# Title     : TODO
# Objective : TODO
# Created by: Administrator
# Created on: 2019/7/24

library(ggplot2)
library(dplyr)
library(tidyr)
library(tibble)
library(ropls)
library(optparse)

createWhenNoExist <- function(f){
    ! dir.exists(f) && dir.create(f)
}

p.cor <- function(n, p, method="pearson"){
    df <- n - 2
    t <- qt(p / 2, df, lower.tail = FALSE)
    r <- switch(method,
    "pearson" = sqrt(t ^ 2 / (df + t ^ 2))
    )
    return(r)
}

option_list <- list(
make_option("--i", default = "AllMet.csv", type = "character", help = "metabolite data file"),
make_option("--g", default = "SampleInfo.csv", type = "character", help = "sample group file")
)
opt <- parse_args(OptionParser(option_list = option_list))

options(digits = 3)

sampleInfo <- read.csv(opt$g, header = T, stringsAsFactors = F) %>%
select(c("SampleID", "ClassNote"))

classNotes <- sampleInfo %>%
.$ClassNote %>%
unique()
cn <- combn(classNotes, 2)

for (i in 1 : ncol(cn)) {
    row <- cn[, i]
    group1Name <- row[1]
    group2Name <- row[2]
    parent <- paste0(group2Name, "_", group1Name)
    createWhenNoExist(parent)
    allFileName <- paste0(parent, "/OPLSDA_VIP_", group2Name, "_", group1Name, "_AllMet.csv")
    outFileName <- paste0(parent, "/OPLSDA_VIPPlot_", group2Name, "_", group1Name, "_nolabel.pdf")
    method <- "pearson"
    n <- nrow(sampleInfo)
    r5 <- p.cor(n, 0.05, method)
    r5s <- c(- r5, r5)
    r1 <- p.cor(n, 0.1, method)
    r1s <- c(- r1, r1)
    plotData <- read.csv(allFileName, header = T) %>%
        select(- c("Class")) %>%
        rowwise() %>%
        do({
            result <- as.data.frame(.)
            p <- result["p"]
            vip <- result["VIP"]
            col <- if (p < 0.05 && vip >= 1) {
                "height"
            }else if ((p >= 0.05 && p <= 0.1) && vip >= 1) {
                "median"
            }else "low"
            result$col <- col
            result
        }) %>%
        mutate(col = factor(col, levels = c("height", "median", "low"))) %>%
        rename(vip = VIP, cor = Corr.Coeffs.) %>%
        as.data.frame()

    print(head(plotData))

    yMax <- max(plotData$vip)
    r1Col <- "#0000FF"
    r5Col <- "#006400"
    breaks <- seq(- 1, 1, 0.2)

    p <- ggplot(plotData, mapping = aes(x = cor, y = vip)) +
        theme_bw(base_size = 8.8, base_family = "Times") +
        theme(axis.text.x = element_text(size = 9, vjust = 0.5),
        axis.text.y = element_text(size = 8.8), legend.position = 'none',
        axis.title.y = element_text(size = 11), legend.margin = margin(t = 0.3, b = 0.1, unit = 'cm'),
        legend.text = element_text(size = 6), axis.title.x = element_text(size = 11), panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), plot.title = element_text(hjust = 0.5, size = 13)
        ) +
        ylab("Variable Importance on Projection (VIP)") +
        geom_hline(aes(yintercept = 1), colour = "#A9A9A9", linetype = 2, size = 0.375) +
        geom_vline(xintercept = r5s, colour = r5Col, linetype = 2, size = 0.4) +
        annotate("text", x = r5 + 0.01 , y = yMax, label = "P=0.05", color = r5Col, hjust = 1 ,
        size = 2, family = "Times", angle = 90, vjust = 1,) +
        annotate("text", x = - r5 - 0.01 , y = yMax, label = "P=0.05", color = r5Col, hjust = 1 ,
        size = 2, family = "Times", angle = 90, vjust = 0) +
        geom_vline(xintercept = r1s, colour = r1Col, linetype = 2, size = 0.4) +
        annotate("text", x = r1 - 0.01 , y = yMax, label = "P=0.1", color = r1Col, hjust = 1 ,
        size = 2, family = "Times", angle = 90, vjust = 0,) +
        annotate("text", x = - r1 + 0.01 , y = yMax, label = "P=0.1", color = r1Col, hjust = 1 ,
        size = 2, family = "Times", angle = 90, vjust = 1,) +
        scale_colour_manual("", values = c("#006400", "#0000FF", "black")) +
        scale_x_continuous("Corr.Coeffs.", breaks = breaks, limits = c(- 1, 1)) +
        geom_text(aes(x = cor, y = vip, colour = col), label = "+", size = 4, family = "Times",
        hjust = 0.5, vjust = 0.3, fontface = "bold")

    ggsave(limitsize = FALSE,outFileName, p, width = 6, height = 4)
}











